package com.zqz.webserver.herocat;

import com.zqz.webserver.servlet.HeroRequest;
import com.zqz.webserver.servlet.HeroResponse;
import com.zqz.webserver.servlet.HeroServlet;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpRequest;

import java.util.Map;

public class CustomHandler extends ChannelInboundHandlerAdapter {

    private final Map<String, HeroServlet> servletMap;
    private final Map<String, String> classNameMap;

    public CustomHandler(Map<String, HeroServlet> servletMap, Map<String, String> classNameMap) {
        this.servletMap = servletMap;
        this.classNameMap = classNameMap;
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest request = (HttpRequest) msg;
            String uri = request.uri();

            // 从请求中解析出要访问的Servlet名称
            String servletName = "";
            if (uri.contains("?") && uri.contains("/")){
                servletName= uri.substring(uri.lastIndexOf("/") + 1, uri.indexOf("?"));
            }

            HeroServlet servlet = new DefaultCustomServlet();
            if (servletMap.containsKey(servletName)) {
                servlet = servletMap.get(servletName);
            } else if (classNameMap.containsKey(servletName)) {
                if (servletMap.get(servletName) == null) {
                    synchronized (this) {
                        if (servletMap.get(servletName) == null) {
                            String className = classNameMap.get(servletName);
                            servlet = (HeroServlet) Class.forName(className).newInstance();
                            servletMap.put(servletName, servlet);
                        }
                    }
                }
            }

            HeroRequest req = new HttpCustomRequest(request);
            HeroResponse res = new HttpCustomResponse(request, ctx);
            // 根据不同的请求类型，调用servlet实例的不同方法
            if (request.method().name().equalsIgnoreCase("GET")) {
                servlet.doGet(req, res);
            } else if(request.method().name().equalsIgnoreCase("POST")) {
                servlet.doPost(req, res);
            }
            ctx.close();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
